.TH std::input_iterator_tag,std::output_iterator_tag,std::forward_iterator_tag, 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::input_iterator_tag,std::output_iterator_tag,std::forward_iterator_tag, \- std::input_iterator_tag,std::output_iterator_tag,std::forward_iterator_tag,

.SH Synopsis
                               std::contiguous_iterator_tag

   Defined in header <iterator>
   struct input_iterator_tag {};                                      \fB(1)\fP
   struct output_iterator_tag {};                                     \fB(2)\fP
   struct forward_iterator_tag : public input_iterator_tag {};        \fB(3)\fP
   struct bidirectional_iterator_tag : public forward_iterator_tag    \fB(4)\fP
   {};
   struct random_access_iterator_tag : public                         \fB(5)\fP
   bidirectional_iterator_tag {};
   struct contiguous_iterator_tag : public random_access_iterator_tag \fB(6)\fP \fI(since C++20)\fP
   {};

   Defines the category of an iterator. Each tag is an empty type.

.SH Notes

   There is no separate tag for LegacyContiguousIterator. That is, it is not possible
   to tell a LegacyContiguousIterator based on its iterator_category.
   To define specialized algorithm for contiguous iterators, use the
   contiguous_iterator concept.
   \fI(since C++20)\fP

   There are no correspondences between output_iterator_tag and the output_iterator
   concept. Setting iterator_concept to output_iterator_tag only indicates that the
   type does not model input_iterator.

.SH Example

   Common technique for algorithm selection based on iterator category tags is to use a
   dispatcher function (the alternative is std::enable_if).
   The iterator tag classes are also used in the corresponding concepts definitions to
   denote the requirements, which can't be expressed in terms of usage patterns alone.
   \fI(since C++20)\fP


// Run this code

 #include <iostream>
 #include <iterator>
 #include <list>
 #include <vector>

 // Using concepts (tag checking is part of the concepts themselves)

 template<std::bidirectional_iterator BDIter>
 void alg(BDIter, BDIter)
 {
     std::cout << "1. alg() \\t called for bidirectional iterator\\n";
 }

 template<std::random_access_iterator RAIter>
 void alg(RAIter, RAIter)
 {
     std::cout << "2. alg() \\t called for random-access iterator\\n";
 }

 // Legacy, using tag dispatch

 namespace legacy
 {
     // Quite often implementation details are hidden in a dedicated namespace
     namespace implementation_details
     {
         template<class BDIter>
         void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
         {
             std::cout << "3. legacy::alg() called for bidirectional iterator\\n";
         }

         template<class RAIter>
         void alg(RAIter, RAIter, std::random_access_iterator_tag)
         {
             std::cout << "4. legacy::alg() called for random-access iterator\\n";
         }
     } // namespace implementation_details

     template<class Iter>
     void alg(Iter first, Iter last)
     {
         implementation_details::alg(first, last,
             typename std::iterator_traits<Iter>::iterator_category());
     }
 } // namespace legacy

 int main()
 {
     std::list<int> l;
     alg(l.begin(), l.end()); // 1.
     legacy::alg(l.begin(), l.end()); // 3.

     std::vector<int> v;
     alg(v.begin(), v.end()); // 2.
     legacy::alg(v.begin(), v.end()); // 4.

 //  std::istreambuf_iterator<char> i1(std::cin), i2;
 //  alg(i1, i2);         // compile error: no matching function for call
 //  legacy::alg(i1, i2); // compile error: no matching function for call
 }

.SH Output:

 1. alg()         called for bidirectional iterator
 3. legacy::alg() called for bidirectional iterator
 2. alg()         called for random-access iterator
 4. legacy::alg() called for random-access iterator

.SH See also

   iterator              base class to ease the definition of required types for simple
   (deprecated in C++17) iterators
                         \fI(class template)\fP
   iterator_traits       provides uniform interface to the properties of an iterator
                         \fI(class template)\fP
